package com.authine.cloudpivot.ext.applicationservice;

import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.ext.applicationservice.base.ApplicationBaseService;
import com.authine.cloudpivot.ext.constants.AppConst;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.dto.*;
import com.authine.cloudpivot.ext.dto.finance.TradeErpPoUpdate;
import com.authine.cloudpivot.ext.enums.order.OrderApproveStatusEnum;
import com.authine.cloudpivot.ext.enums.order.OrderCustomerStatusEnum;
import com.authine.cloudpivot.ext.enums.order.OrderGoodsStatusEnum;
import com.authine.cloudpivot.ext.enums.report.ReportType;
import com.authine.cloudpivot.ext.service.ContractService;
import com.authine.cloudpivot.ext.service.DockFinanceService;
import com.authine.cloudpivot.ext.service.OrderService;
import com.authine.cloudpivot.ext.service.impl.ContractServiceImpl;
import com.authine.cloudpivot.ext.service.impl.DockFinanceServiceImpl;
import com.authine.cloudpivot.ext.service.impl.OrderServiceImpl;
import com.authine.cloudpivot.ext.utils.BoResultFormat;
import com.authine.cloudpivot.ext.utils.BoServiceUtils;
import com.authine.cloudpivot.ext.utils.JdbcTemplateUtils;
import com.authine.cloudpivot.ext.utils.StringUtils;
import com.authine.cloudpivot.ext.utils.boQuery.BoQueryUtils;
import com.authine.cloudpivot.ext.utils.kingdee.DateUtils;
import com.authine.cloudpivot.ext.utils.system.ReportUtils;
import com.authine.cloudpivot.ext.utils.*;
import com.authine.cloudpivot.ext.vo.CustomerOrderVo;
import com.authine.common.json.JsonUtils;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import com.authine.mvp.app.launcher.rpc.SaveOrUpdateBO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

/**
 * @ClassName CustomerOrderService
 * @Description: 采购订单自定义服务
 * @Author cjj
 * @Date 2021/4/20
 * @Version V1.0
 **/
@Path("CustomerOrderService")
@Slf4j
public class CustomerOrderService extends ApplicationBaseService {
    private OrderService orderService = new OrderServiceImpl();
    private DockFinanceService dockFinanceService = new DockFinanceServiceImpl();
    private ContractService contractService = new ContractServiceImpl();
    private NamedParameterJdbcTemplate jdbcTemplate = ApplicationContextUtils.getBean(NamedParameterJdbcTemplate.class);

    /**
     * 修改ErpPO
     *
     * @param dto
     * @return
     */
    @Path("updateErpPO")
    @POST
    @Operation(summary = "采购订单-全部-修改ErpPO", tags = CUSTOM_SERVICE)
    public SingleResponse<Boolean> updateErpPO(@Parameter OrderCustomerDto dto) {
        log.info("------------------------采购订单-全部-修改ErpPO updateErpPO Param：{}------------------------", JSONObject.toJSONString(dto));
        if (StringUtils.isBlank(dto.getId()) || StringUtils.isBlank(dto.getErpPO())) {
            return SingleResponse.buildFailure("-1", "参数不合法");
        }
        Integer i = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR).putFieldAndVal("erp_po", dto.getErpPO())
                .eq("order_customer_id", dto.getId()).update();
        //联动修改客户订单表erpPO和供应商订单商品erpPO
        JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER).putFieldAndVal("erp_po", dto.getErpPO())
                .eq("id", dto.getId()).update();
        JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR_GOODS).putFieldAndVal("erp_po", dto.getErpPO())
                .eq("order_customer_id", dto.getId()).update();
        JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER_GOODS).putFieldAndVal("erp_po", dto.getErpPO())
                .eq("order_customer_id", dto.getId()).update();
        dockFinanceService.writeBackErpPo(Collections.singletonList(new TradeErpPoUpdate(dto.getId(), dto.getErpPO())));
        return SingleResponse.of(i >= 0 ? true : false);
    }

    /**
     * 批量修改客户订单状态
     *
     * @param dto
     * @return
     */
    @Path("batchUpdateOrderCustomer")
    @POST
    @Operation(summary = "采购订单-批量修改客户订单状态（批量取消/批量付款/提交审批）", tags = CUSTOM_SERVICE)
    public SingleResponse batchUpdateOrderCustomer(@Parameter OrderCustomerDto dto) {
        log.info("------------------------采购订单-批量修改客户订单状态（批量取消/批量付款/提交审批） batchUpdateOrderCustomer Param：{}------------------------", JSONObject.toJSONString(dto));
        if (CollectionUtils.isEmpty(dto.getIds()) || null == dto.getOrderCustomerStatus()) {
            return SingleResponse.buildFailure("-1", "参数不合法");
        }
        return orderService.batchUpdateOrderCustomer(dto);
    }

    /**
     * 代发货listBo
     *
     * @param dto
     * @return
     */
    @Path("listBoPackaging")
    @POST
    @Operation(summary = "采购订单-代发货-全部列表分页查询", tags = CUSTOM_SERVICE)
    public SingleResponse<BOList> listBoPackaging(@Parameter OrderCustomerGoodsDto dto) {
        log.info("------------------------采购订单-代发货-全部列表分页查询 listBoPackaging Param：{}------------------------", JsonUtils.toJson(dto));
        if (null == dto.getPageIndex() || null == dto.getPageSize()) {
            return SingleResponse.buildFailure("-1", "pageIndex、pageSize必填");
        }
        String tableName = getTableName(ModelConst.T_ORDER_CUSTOMER_GOODS);
        String relationTableName = getTableName(ModelConst.T_ORDER_GOODS_RELATION);
        Map<String, Object> parameter = new HashMap<>();
        StringBuilder listSql = new StringBuilder();
        StringBuilder whereSql = new StringBuilder();
        StringBuilder countSql = new StringBuilder();
        listSql.append("select * from " + tableName + " cg " +
                "left join " + relationTableName + " gr on cg.relation_id = gr.id " +
                "where cg.deleted ='0' and cg.order_customer_goods_status in ('" + OrderCustomerStatusEnum.UpcomingConfirm.name() + "', '" + OrderCustomerStatusEnum.UpcomingDelivery.name() + "') ");
        countSql.append("select count(*) from " + tableName + " cg " +
                "left join " + relationTableName + " gr on cg.relation_id = gr.id " +
                "where cg.deleted ='0' and cg.order_customer_goods_status in ('" + OrderCustomerStatusEnum.UpcomingConfirm.name() + "', '" + OrderCustomerStatusEnum.UpcomingDelivery.name() + "') ");
        //拼接参数
        if (StringUtils.isNotBlank(dto.getId())) {
            List<String> ids = StringUtils.stringToListString(dto.getId(), ";");
            whereSql.append(" and cg.id in (:id) ");
            parameter.put("id", ids);
        }
        if (StringUtils.isNotBlank(dto.getOrderCustomerId())) {
            List<String> orderCustomerIds = StringUtils.stringToListString(dto.getOrderCustomerId(), ";");
            whereSql.append(" and cg.order_customer_id in (:order_customer_id) ");
            parameter.put("order_customer_id", orderCustomerIds);
        }
        if (StringUtils.isNotBlank(dto.getVendorOrganizationName())) {
            whereSql.append(" and cg.vendor_organization_name like :vendor_organization_name ");
            parameter.put("vendor_organization_name", "%" + dto.getVendorOrganizationName() + "%");
        }
        if (StringUtils.isNotBlank(dto.getBrand())) {
            whereSql.append("and cg.brand like :brand ");
            parameter.put("brand", "%" + dto.getBrand() + "%");
        }
        if (StringUtils.isNotBlank(dto.getName())) {
            whereSql.append(" and cg.name like :name ");
            parameter.put("name", "%" + dto.getName() + "%");
        }
        if (StringUtils.isNotBlank(dto.getModel())) {
            whereSql.append(" and cg.model like :model ");
            parameter.put("model", "%" + dto.getModel() + "%");
        }
        if (StringUtils.isNotBlank(dto.getSpec())) {
            whereSql.append(" and cg.spec like :spec ");
            parameter.put("spec", "%" + dto.getSpec() + "%");
        }
        if (StringUtils.isNotBlank(dto.getOrderCustomerGoodsStatus())) {
            whereSql.append(" and cg.order_customer_goods_status like :order_customer_goods_status ");
            parameter.put("order_customer_goods_status", dto.getOrderCustomerGoodsStatus());
        }
        if (StringUtils.isNotBlank(dto.getStartTime()) && StringUtils.isNotBlank(dto.getEndTime())) {
            whereSql.append(" and cg.place_order_time between :startTime and :endTime ");
            parameter.put("startTime", dto.getStartTime());
            parameter.put("endTime", dto.getEndTime());
        }
        countSql.append(whereSql);
        listSql.append(whereSql);
        listSql.append(" order by cg.createdTime desc");
        listSql.append(" limit " + dto.getPageIndex() * dto.getPageSize() + ", " + dto.getPageSize());
        log.info("------------------------采购订单-代发货-全部列表分页查询 listBoPackaging listSql：{}------------------------parameter：{}", listSql, JsonUtils.toJson(parameter));
        log.info("------------------------采购订单-代发货-全部列表分页查询 listBoPackaging whereSql：{}------------------------parameter：{}", whereSql, listSql, JsonUtils.toJson(parameter));
        List<Map<String, Object>> resultList = jdbcTemplate.queryForList(listSql.toString(), parameter);
        Integer count = 0;
        try {
            count = jdbcTemplate.queryForObject(countSql.toString(), parameter, Integer.class);
        } catch (DataAccessException e) {
            e.printStackTrace();
        }
        //构建结果集
        BoResultFormat.resultFormat(resultList, ModelConst.T_ORDER_CUSTOMER_GOODS);
        BOList bOList = new BOList();
        bOList.setData(resultList);
        bOList.setTotal(count);
        bOList.setSchemaCode(ModelConst.T_ORDER_CUSTOMER_GOODS);
        return SingleResponse.of(bOList);
    }

    /**
     * 待收货listBo
     *
     * @param dto
     * @return
     */
    @Path("listBoDelivery")
    @POST
    @Operation(summary = "采购订单-待收货-待收货列表分页查询", tags = CUSTOM_SERVICE)
    public SingleResponse<BOList> listBoDelivery(@Parameter OrderCustomerGoodsDto dto) {
        dto.setOrderCustomerGoodsStatus(OrderGoodsStatusEnum.DoneDelivery.name());
        return deliveryList(dto);
    }

    /**
     * 全部listBo
     *
     * @param dto
     * @return
     */
    @Path("listBoAll")
    @POST
    @Operation(summary = "采购订单-全部-全部列表分页查询", tags = CUSTOM_SERVICE, description = "pageIndex、pageSize必填")
    public SingleResponse<BOList> listBoAll(@Parameter OrderCustomerDto dto) {
        log.info("------------------------采购订单-全部-全部列表分页查询 listBoAll Param：{}------------------------", JsonUtils.toJson(dto));
        if (null == dto.getPageIndex() || null == dto.getPageSize()) {
            return SingleResponse.buildFailure("-1", "pageIndex、pageSize必填");
        }
        String tableName = getTableName(ModelConst.T_ORDER_CUSTOMER);
        Map<String, Object> parameter = new HashMap<>();
        StringBuilder listSql = new StringBuilder();
        StringBuilder whereSql = new StringBuilder();
        StringBuilder countSql = new StringBuilder();
        listSql.append("select * from " + tableName + " where deleted ='0' and order_customer_status <> '"+OrderCustomerStatusEnum.Closed.name()+"' ");
        countSql.append("select count(*) from " + tableName + " where deleted ='0' and order_customer_status <> '"+OrderCustomerStatusEnum.Closed.name()+"' ");
        //拼接参数
        if (StringUtils.isNotBlank(dto.getId())) {
            List<String> ids = StringUtils.stringToListString(dto.getId(), ";");
            whereSql.append(" and id in (:id) ");
            parameter.put("id", ids);
        }
        if (StringUtils.isNotBlank(dto.getErpPO())) {
            List<String> erpPo = StringUtils.stringToListString(dto.getErpPO(), ";");
            whereSql.append(" and erp_po in (:erp_po) ");
            parameter.put("erp_po", erpPo);
        }
        if (StringUtils.isNotBlank(dto.getPlaceOrderFullname())) {
            whereSql.append(" and place_order_fullname like :placeOrderFullname ");
            parameter.put("placeOrderFullname", "%" + dto.getPlaceOrderFullname() + "%");
        }
        if (StringUtils.isNotBlank(dto.getOrganizationName())) {
            whereSql.append("and organization_name like :organizationName ");
            parameter.put("organizationName", "%" + dto.getOrganizationName() + "%");
        }
        if (StringUtils.isNotBlank(dto.getReceiver())) {
            whereSql.append(" and receiver like :receiver ");
            parameter.put("receiver", "%" + dto.getReceiver() + "%");
        }
        if (StringUtils.isNotBlank(dto.getPhone())) {
            whereSql.append(" and phone like :phone ");
            parameter.put("phone", "%" + dto.getPhone() + "%");
        }
        if (StringUtils.isNotBlank(dto.getPostal())) {
            whereSql.append(" and postal like :postal ");
            parameter.put("postal", "%" + dto.getPostal() + "%");
        }
        if (StringUtils.isNotBlank(dto.getAddress())) {
            whereSql.append(" and address like :address ");
            parameter.put("address", "%" + dto.getAddress() + "%");
        }
        if (null != dto.getOrderCustomerStatus()) {
            whereSql.append(" and order_customer_status =:status ");
            parameter.put("status", dto.getOrderCustomerStatus().name());
        }
        if (StringUtils.isNotBlank(dto.getStartTime()) && StringUtils.isNotBlank(dto.getEndTime())) {
            whereSql.append(" and place_order_time between :startTime and :endTime ");
            parameter.put("startTime", dto.getStartTime());
            parameter.put("endTime", dto.getEndTime());
        }
        countSql.append(whereSql);
        listSql.append(whereSql);
        listSql.append(" order by createdTime desc");
        listSql.append(" limit " + dto.getPageIndex() * dto.getPageSize() + ", " + dto.getPageSize());
        log.info("------------------------采购订单-全部-全部列表分页查询 listBoAll listSql：{}------------------------parameter：{}", listSql, JsonUtils.toJson(parameter));
        log.info("------------------------采购订单-全部-全部列表分页查询 listBoAll whereSql：{}------------------------parameter：{}", whereSql, listSql, JsonUtils.toJson(parameter));
        List<Map<String, Object>> resultList = jdbcTemplate.queryForList(listSql.toString(), parameter);
        Integer count = 0;
        try {
            count = jdbcTemplate.queryForObject(countSql.toString(), parameter, Integer.class);
        } catch (DataAccessException e) {
            e.printStackTrace();
        }
        for (Map<String, Object> map : resultList) {
            if (null != map.get("extends_attr") && !map.get("extends_attr").equals("")) {
                Map<String, Object> extendsAttr = (Map) JSONObject.parse((String) map.get("extends_attr"));
                String approvalBy = (String) extendsAttr.get("approvalBy");
                String approvalOpinion = (String) extendsAttr.get("approvalOpinion");
                map.put("approval_by", approvalBy);
                map.put("approval_opinion", approvalOpinion);
            }
        }
        //构建结果集
        BoResultFormat.resultFormat(resultList, ModelConst.T_ORDER_CUSTOMER);
        BOList bOList = new BOList();
        bOList.setData(resultList);
        bOList.setTotal(count);
        bOList.setSchemaCode(ModelConst.T_ORDER_CUSTOMER);
        return SingleResponse.of(bOList);
    }

    /**
     * 代付款listBo
     *
     * @param dto
     * @return
     */
    @Path("listCustomerPayment")
    @POST
    @Operation(summary = "采购订单-代付款-列表分页查询", tags = CUSTOM_SERVICE, description = "pageIndex、pageSize必填")
    public SingleResponse<BOList> listCustomerPayment(@Parameter OrderCustomerDto dto) {
        log.info("------------------------采购订单-代付款-列表分页查询 listCustomerPayment Param：{}------------------------", JsonUtils.toJson(dto));
        if (null == dto.getPageIndex() || null == dto.getPageSize()) {
            return SingleResponse.buildFailure("-1", "pageIndex、pageSize必填");
        }
        String tableName = getTableName(ModelConst.T_ORDER_CUSTOMER);
        Map<String, Object> parameter = new HashMap<>();
        StringBuilder listSql = new StringBuilder();
        StringBuilder whereSql = new StringBuilder();
        StringBuilder countSql = new StringBuilder();
        listSql.append("select * from " + tableName + " where deleted ='0' and label NOT LIKE '%" + OrderApproveStatusEnum.APPROVED.getId() + "%'  and order_customer_status ='" + OrderCustomerStatusEnum.UpcomingPayment.name() + "'");
        countSql.append("select count(*) from " + tableName + " where deleted ='0' and label NOT LIKE '%" + OrderApproveStatusEnum.APPROVED.getId() + "%'  and order_customer_status ='" + OrderCustomerStatusEnum.UpcomingPayment.name() + "' ");
        //拼接参数
        if (StringUtils.isNotBlank(dto.getId())) {
            List<String> ids = StringUtils.stringToListString(dto.getId(), ";");
            whereSql.append(" and id in (:id) ");
            parameter.put("id", ids);
        }
        if (StringUtils.isNotBlank(dto.getOrganizationName())) {
            whereSql.append("and organization_name like :organizationName ");
            parameter.put("organizationName", "%" + dto.getOrganizationName() + "%");
        }
        if (StringUtils.isNotBlank(dto.getReceiver())) {
            whereSql.append(" and receiver like :receiver ");
            parameter.put("receiver", "%" + dto.getReceiver() + "%");
        }
        if (StringUtils.isNotBlank(dto.getPhone())) {
            whereSql.append(" and phone like :phone ");
            parameter.put("phone", "%" + dto.getPhone() + "%");
        }
        if (StringUtils.isNotBlank(dto.getPostal())) {
            whereSql.append(" and postal like :postal ");
            parameter.put("postal", "%" + dto.getPostal() + "%");
        }
        if (StringUtils.isNotBlank(dto.getAddress())) {
            whereSql.append(" and address like :address ");
            parameter.put("address", "%" + dto.getAddress() + "%");
        }
        if (StringUtils.isNotBlank(dto.getStartTime()) && StringUtils.isNotBlank(dto.getEndTime())) {
            whereSql.append(" and place_order_time between :startTime and :endTime ");
            parameter.put("startTime", dto.getStartTime());
            parameter.put("endTime", dto.getEndTime());
        }
        countSql.append(whereSql);
        listSql.append(whereSql);
        listSql.append(" order by createdTime desc");
        listSql.append(" limit " + dto.getPageIndex() * dto.getPageSize() + ", " + dto.getPageSize());
        log.info("------------------------采购订单-代付款-列表分页查询 listCustomerPayment listSql：{}------------------------parameter：{}", listSql, JsonUtils.toJson(parameter));
        List<Map<String, Object>> resultList = jdbcTemplate.queryForList(listSql.toString(), parameter);
        Integer count = 0;
        try {
            count = jdbcTemplate.queryForObject(countSql.toString(), parameter, Integer.class);
        } catch (DataAccessException e) {
            e.printStackTrace();
        }
        //构建结果集
        BoResultFormat.resultFormat(resultList, ModelConst.T_ORDER_CUSTOMER);
        BOList bOList = new BOList();
        bOList.setData(resultList);
        bOList.setTotal(count);
        bOList.setSchemaCode(ModelConst.T_ORDER_CUSTOMER);
        return SingleResponse.of(bOList);
    }

    /**
     * 已驳回/修改订单信息
     *
     * @param dto
     * @return
     */
    @Path("updateOrderInfo")
    @POST
    @Operation(summary = "采购订单-已驳回-修改订单信息", tags = CUSTOM_SERVICE, description = "id必填")
    public SingleResponse<BO> updateOrderInfo(@Parameter OrderCustomerDto dto) {
        log.info("------------------------采购订单-已驳回-修改订单信息 updateOrderInfo Param：{}------------------------", JSONObject.toJSONString(dto));
        if (StringUtils.isBlank(dto.getId())) {
            return SingleResponse.buildFailure("-1", "客户订单ID必填");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("id", dto.getId());
        map.put("erp_po", dto.getErpPO());
        map.put("receiver", dto.getReceiver());
        map.put("phone", dto.getPhone());
        map.put("postal", dto.getPostal());
        map.put("address", dto.getAddress());
        SingleResponse<BO> result = BoServiceUtils.updateMainBo(ModelConst.T_ORDER_CUSTOMER, map);
        log.info("------------------------采购订单-已驳回-修改订单信息 updateOrderInfo Result：{}------------------------", JSONObject.toJSONString(result));
        return result;
    }

    /**
     * 订单商品修改送货要求
     *
     * @param dto
     * @return
     */
    @Path("updateDeliveryRequirements")
    @POST
    @Operation(summary = "采购订单-订单商品-修改送货要求", tags = CUSTOM_SERVICE, description = "id、deliveryRequirements必填")
    public SingleResponse<BO> updateDeliveryRequirements(@Parameter OrderGoodsRelationDto dto) {
        log.info("------------------------updateDeliveryRequirements Param：{}------------------------", JSONObject.toJSONString(dto));
        if (StringUtils.isBlank(dto.getId())) {
            return SingleResponse.buildFailure("-1", "订单商品关系ID必填");
        }
        if (StringUtils.isBlank(dto.getDeliveryRequirements())) {
            return SingleResponse.buildFailure("-1", "送货要求必填");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("id", dto.getId());
        map.put("delivery_requirements", dto.getDeliveryRequirements());
        SingleResponse<BO> result = BoServiceUtils.updateMainBo(ModelConst.T_ORDER_GOODS_RELATION, map);
        log.info("------------------------updateDeliveryRequirements Result：{}------------------------", JSONObject.toJSONString(result));
        return result;
    }

    /**
     * 发票信息
     *
     * @param dto
     * @return
     */
    @Path("invoiceDetail")
    @POST
    @Operation(summary = "采购订单-订单商品-发票信息", tags = CUSTOM_SERVICE, description = "id必填")
    public SingleResponse<BOList> invoiceDetail(@Parameter OrderCustomerGoodsDto dto) {
        log.info("------------------------采购订单-订单商品-发票信息 invoiceDetail Param：{}------------------------", JSONObject.toJSONString(dto));
        if (StringUtils.isBlank(dto.getId())) {
            return SingleResponse.buildFailure("-1", "客户订单商品ID必填");
        }
        String invoiceDetailTableName = getTableName(AppConst.FINANCIALCENTER, ModelConst.T_INVOICE_DETAIL);
        String invoiceApplyTableName = getTableName(AppConst.FINANCIALCENTER, ModelConst.T_INVOICE_APPLY);
        String tradeTableName = getTableName(AppConst.FINANCIALCENTER, ModelConst.T_TRADE);
        String sql = "SELECT apply.ID,apply.number,apply.code, apply.date FROM " + invoiceDetailTableName + " detail " +
                "    LEFT JOIN " + invoiceApplyTableName + " apply ON apply.ID = detail.invoice_apply_id " +
                "    LEFT JOIN " + tradeTableName + " trade ON trade.ID = detail.trade_id " +
                "    WHERE detail.deleted = '0' AND apply.deleted = '0' " +
                "    AND trade.order_goods_id ='" + dto.getId() + "'" +
                "    AND apply.status = 'Done'";
        List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, new HashMap<>());
        log.info("------------------------采购订单-订单商品-发票信息 invoiceDetail Result：{}------------------------", JSONObject.toJSONString(result));
        //构建结果集
        BOList bOList = new BOList();
        bOList.setData(result);
        bOList.setTotal(result.size());
        bOList.setSchemaCode(ModelConst.T_INVOICE_APPLY);
        return SingleResponse.of(bOList);
    }

    /**
     * 已驳回listBo
     *
     * @param dto
     * @return
     */
    @Path("listCustomerRejected")
    @POST
    @Operation(summary = "采购订单-已驳回-列表分页查询", tags = CUSTOM_SERVICE, description = "pageIndex、pageSize必填")
    public SingleResponse<BOList> listCustomerRejected(@Parameter OrderCustomerDto dto) {
        log.info("------------------------采购订单-已驳回-列表分页查询 listCustomerRejected Param：{}------------------------", JsonUtils.toJson(dto));
        if (null == dto.getPageIndex() || null == dto.getPageSize()) {
            return SingleResponse.buildFailure("-1", "pageIndex、pageSize必填");
        }
        String tableName = getTableName(ModelConst.T_ORDER_CUSTOMER);
        Map<String, Object> parameter = new HashMap<>();
        StringBuilder listSql = new StringBuilder();
        StringBuilder whereSql = new StringBuilder();
        StringBuilder countSql = new StringBuilder();
        listSql.append("select * from " + tableName + " where deleted ='0' and approval_opinion is not null and approval_opinion <> '' and order_customer_status ='" + OrderCustomerStatusEnum.UpcomingPayment.name() + "'");
        countSql.append("select count(*) from " + tableName + " where deleted ='0' and approval_opinion is not null and approval_opinion <> '' and order_customer_status ='" + OrderCustomerStatusEnum.UpcomingPayment.name() + "' ");
        //拼接参数
        if (StringUtils.isNotBlank(dto.getId())) {
            List<String> ids = StringUtils.stringToListString(dto.getId(), ";");
            whereSql.append(" and id in (:id) ");
            parameter.put("id", ids);
        }
        if (StringUtils.isNotBlank(dto.getOrganizationName())) {
            whereSql.append("and organization_name like :organizationName ");
            parameter.put("organizationName", "%" + dto.getOrganizationName() + "%");
        }
        if (StringUtils.isNotBlank(dto.getReceiver())) {
            whereSql.append(" and receiver like :receiver ");
            parameter.put("receiver", "%" + dto.getReceiver() + "%");
        }
        if (StringUtils.isNotBlank(dto.getPhone())) {
            whereSql.append(" and phone like :phone ");
            parameter.put("phone", "%" + dto.getPhone() + "%");
        }
        if (StringUtils.isNotBlank(dto.getPostal())) {
            whereSql.append(" and postal like :postal ");
            parameter.put("postal", "%" + dto.getPostal() + "%");
        }
        if (StringUtils.isNotBlank(dto.getAddress())) {
            whereSql.append(" and address like :address ");
            parameter.put("address", "%" + dto.getAddress() + "%");
        }
        if (StringUtils.isNotBlank(dto.getStartTime()) && StringUtils.isNotBlank(dto.getEndTime())) {
            whereSql.append(" and place_order_time between :startTime and :endTime ");
            parameter.put("startTime", dto.getStartTime());
            parameter.put("endTime", dto.getEndTime());
        }
        countSql.append(whereSql);
        listSql.append(whereSql);
        listSql.append(" order by createdTime desc");
        listSql.append(" limit " + dto.getPageIndex() * dto.getPageSize() + ", " + dto.getPageSize());
        log.info("------------------------采购订单-已驳回-列表分页查询 listCustomerRejected listSql：{}------------------------parameter：{}", listSql, JsonUtils.toJson(parameter));
        List<Map<String, Object>> resultList = jdbcTemplate.queryForList(listSql.toString(), parameter);
        Integer count = 0;
        try {
            count = jdbcTemplate.queryForObject(countSql.toString(), parameter, Integer.class);
        } catch (DataAccessException e) {
            e.printStackTrace();
        }
        //构建结果集
        BoResultFormat.resultFormat(resultList, ModelConst.T_ORDER_CUSTOMER);
        BOList bOList = new BOList();
        bOList.setData(resultList);
        bOList.setTotal(count);
        bOList.setSchemaCode(ModelConst.T_ORDER_CUSTOMER);
        return SingleResponse.of(bOList);
    }

    /**
     * 采购订单-全部、已付款-导出列表
     *
     * @param bo
     * @return
     */
    @Path("exportOrderCustomerAll")
    @POST
    @Operation(summary = "采购订单-全部、已付款-导出列表", tags = CUSTOM_SERVICE, description = "入参:{data:{ids:[],fileType:'pdf/xlsx'}}")
    public SingleResponse exportOrderCustomerAll(SaveOrUpdateBO bo) {
        List<String> ids = (List<String>) bo.getData().get("ids");
        if (ObjectUtils.isEmpty(ids)) {
            return SingleResponse.buildFailure("-1", "请求参数ids不能为空");
        }

        String fileType = (String) bo.getData().get("fileType");
        ReportType reportType = ReportType.get(fileType);

        if (reportType == null) {
            return SingleResponse.buildFailure("-1", "请求参数fileType不能为空");
        }

        SingleResponse<BOList> singleResponse = BoQueryUtils.Builder(ModelConst.T_ORDER_CUSTOMER)
                .condition()
                .in("id", ids)
                .End().listBO();
        if (!singleResponse.isSuccess()) {
            return singleResponse;
        }
        List<Map<String, Object>> data = singleResponse.getData().getData();

        if (data.isEmpty()) {
            return SingleResponse.buildFailure("-1", "未获取到下载数据");
        }

        String exportField = "{\"id\":\"id\",\"time\":\"createdTime\",\"freight\":\"freight\",\"total\":\"total\",\"amount\":\"amount\",\"receiver\":\"receiver\",\"phone\":\"phone\",\"address\":\"address\",\"status\":\"order_customer_status\",\"memberName\":\"place_order_fullname\",\"orgName\":\"organization_name\",\"erpPO\":\"erp_po\"}";
        JSONObject exportJson = JSON.parseObject(exportField);
        List<Map<String, Object>> fileData = data.stream().map(m -> {
            Map<String, Object> mf = new HashMap<>();
            for (String key : exportJson.keySet()) {
                mf.put(exportJson.getString(key), m.get(key));
            }
            return mf;
        }).collect(Collectors.toList());


        if (log.isDebugEnabled()) {
            log.debug("======================采购订单-全部-导出参数:reportType={},fileData={}", reportType.getId(), JSON.toJSONString(fileData));
        }
        ReportUtils.exportReport("order/customer_order_report_xlsx.jrxml", reportType.getId(), fileData);

        return SingleResponse.buildSuccess();
    }

    /**
     * 采购订单-数据分析-导出列表
     *
     * @param bo
     * @return
     */
    @Path("exportOrderTpiReport")
    @POST
    @Operation(summary = "采购订单-数据分析-导出列表", tags = CUSTOM_SERVICE, description = "入参:{data:{ids:[],fileType:'pdf/xlsx'}}")
    public SingleResponse exportOrderTpiReport(SaveOrUpdateBO bo) {
        List<String> ids = (List<String>) bo.getData().get("ids");
        if (ObjectUtils.isEmpty(ids)) {
            return SingleResponse.buildFailure("-1", "请求参数ids不能为空");
        }

        String fileType = (String) bo.getData().get("fileType");
        ReportType reportType = ReportType.get(fileType);

        String o = getTableName(ModelConst.T_ORDER_CUSTOMER_GOODS);
        String v = getTableName(ModelConst.T_ORDER_VENDOR);
        String c = getTableName(ModelConst.T_ORDER_CUSTOMER);
        String ogr = getTableName(ModelConst.T_ORDER_GOODS_RETURNS);
        String r = getTableName(ModelConst.T_ORDER_GOODS_ACCEPT);
        String gp = getTableName(ModelConst.T_MEMBER_PURCHASE_ORDER_GOODS);
        String qg = getTableName(ModelConst.T_QUOTATION_GOODS);
        String iq = getTableName(ModelConst.T_INQUIRY_GOODS);
        StringBuilder listSql = new StringBuilder();
        Map<String, Object> parameter = new HashMap<>();
        listSql.append( "select a.*,b.min_price, \n" +
                "        CASE \n" +
                "        WHEN  b.min_price is null THEN\n" +
                "        '是'\n" +
                "        WHEN a.price <= b.min_price  THEN\n" +
                "        '是'\n" +
                "        else\n" +
                "        '否'\n" +
                "        END as  bol_lowest\n" +
                "        , CASE \n" +
                "        WHEN b.min_price is null  THEN\n" +
                "           '0.0000'\n" +
                "        else\n" +
                "        round(b.min_price,4) -  round(a.price,4)\n" +
                "        END as price_diff\n" +
                "        ,CASE \n" +
                "        WHEN b.min_price is null  THEN\n" +
                "           '0.00'\n" +
                "        else\n" +
                "        round(round(a.num,4) * (round(b.min_price,4) -  round(a.price,4)),2)\n" +
                "        END as  amount_diff\n" +
                "        ,iq.delivery as inqury_delivery\n" +
                "        from (\n" +
                "        select  o.erp_po,o.id \n" +
                "        ,o.name ,o.brand ,o.model ,o.inquiry_member_name ,o.customer_order_id \n" +
                "        ,round(o.quantity,4) num \n" +
                "        ,o.price \n" +
                "        ,o.amount \n" +
                "        ,o.delivery \n" +
                "        ,o.delivery_time \n" +
                "        , CASE \n" +
                "        WHEN o.actual_deliver_time is null  THEN\n" +
                "         max(o.receive_time)\n" +
                "        else\n" +
                "        o.actual_deliver_time\n" +
                "        END as  actual_deliver_time\n" +
                "        ,o.bol_refund \n" +
                "        ,group_concat(memo ,'---') refund_reson\n" +
                "        ,o.createdTime \n" +
                "        ,o.organization_name \n" +
                "        ,o.bol_invite \n" +
                "        , CASE \n" +
                "        WHEN o.actual_deliver_time is null and max(o.receive_time) is null THEN\n" +
                "        ' '\n" +
                "        WHEN  o.actual_deliver_time is null and max(o.receive_time) > o.delivery_time THEN\n" +
                "         '否'\n" +
                "        WHEN  o.actual_deliver_time is not null and o.actual_deliver_time > o.delivery_time  THEN\n" +
                "         '否'\n" +
                "        ELSE\n" +
                "         '是'\n" +
                "        END as bol_ontime\n" +
                "        ,o.inquiry_goods_id\n" +
                "        from (\n" +
                "        select o.id ,o.name,o.brand,o.model,c.place_order_fullname,c.id customer_order_id,o.quantity,o.price ,o.amount ,c.erp_po ,o.inquiry_member_name,o.delivery_time\n" +
                "        ,o.delivery ,o.createdTime + (o.delivery || ' day'),o.createdTime ,v.organization_name ,ogr.memo \n" +
                "        ,o.actual_deliver_time,r.createdTime receive_time,qg.inquiry_goods_id,\n" +
                "        CASE \n" +
                "        WHEN ogr.memo is null THEN\n" +
                "        '否'\n" +
                "        ELSE\n" +
                "        '是'\n" +
                "        END as bol_refund,\n" +
                "        CASE \n" +
                "        WHEN v.data_sources THEN\n" +
                "        '是'\n" +
                "        ELSE\n" +
                "        '否'\n" +
                "        END as bol_invite\n" +
                "        from  i_ordercenter_t_order_customer_goods o\n" +
                "        left join i_ordercenter_t_order_vendor v on o.order_vendor_id =v.id \n" +
                "        left join i_ordercenter_t_order_customer c on v.order_customer_id =c.id \n" +
                "        left join i_ordercenter_t_order_goods_returns ogr on ogr.order_customer_goods_id =o.id\n" +
                "        left join i_ordercenter_t_order_goods_accept r on r.order_customer_goods_id =o.id\n" +
                "        left join commoditymaterials.i_commoditymaterials_t_goods_purchase gp on gp.id =o.goods_id\n" +
                "        left join sourcingcenter.i_sourcingcenter_t_quotation_goods qg on qg.id =gp.quotation_goods_id\n" +
                "        where c.id  in (:id)\n" +
                "        )o\n" +
                "        group by o.id ,o.name,o.brand,o.model,o.inquiry_member_name,o.customer_order_id ,o.quantity,o.price ,o.amount,o.erp_po \n" +
                "        ,o.delivery ,o.delivery_time,o.createdTime ,o.organization_name\n" +
                "        ,o.bol_refund,o.bol_invite,o.actual_deliver_time,o.inquiry_goods_id)a\n" +
                "        left join (\n" +
                "        SELECT qg.inquiry_goods_id,min(qg.price) min_price from sourcingcenter.i_sourcingcenter_t_quotation_goods qg where qg.inquiry_goods_id in( select qg.inquiry_goods_id from (select id,goods_id,order_vendor_id from i_ordercenter_t_order_customer_goods)o\n" +
                "        left join i_ordercenter_t_order_vendor v on o.order_vendor_id =v.id \n" +
                "        left join i_ordercenter_t_order_customer c on v.order_customer_id =c.id \n" +
                "        left join i_ordercenter_t_order_goods_returns ogr on ogr.order_customer_goods_id =o.id\n" +
                "        left join i_ordercenter_t_order_goods_accept r on r.order_customer_goods_id =o.id\n" +
                "        left join commoditymaterials.i_commoditymaterials_t_goods_purchase gp on gp.id =o.goods_id\n" +
                "        left join sourcingcenter.i_sourcingcenter_t_quotation_goods qg on qg.id =gp.quotation_goods_id \n" +
                "     where c.id  in (:id)\n" +
                "        ) and qg.status =6 GROUP BY qg.inquiry_goods_id\n" +
                "        )b on a.inquiry_goods_id =b.inquiry_goods_id\n" +
                "        left join sourcingcenter.i_sourcingcenter_t_inquiry_goods iq on a.inquiry_goods_id =iq.id\n" +
                "         order by a.id desc\n" +
                " ");
        parameter.put("id", ids);
        if (reportType == null) {
            return SingleResponse.buildFailure("-1", "请求参数fileType不能为空");
        }
        log.info("------------------------采购订单-数据分析-导出参数 exporPurchasePaymentReport listSql：{}------------------------parameter：{}", listSql, JsonUtils.toJson(ids));
        List<Map<String, Object>> data = jdbcTemplate.queryForList(listSql.toString(),parameter);

        if (data.isEmpty()) {
            return SingleResponse.buildFailure("-1", "未获取到下载数据");
        }

        String exportField = "{\"time\":\"createdTime\",\"brand\":\"brand\",\"name\":\"name\",\"model\":\"model\",\"bolRufund\":\"bol_refund\",\"delivery\":\"delivery\",\"num\":\"quantity\",\"bolOntime\":\"bol_ontime\",\"price\":\"price\",\"bolInvite\":\"bol_invite\",\"amount\":\"amount\",\"refundReason\":\"refund_reason\",\"bolLowest\":\"bol_lowest\",\"id\":\"id\",\"deliveryTime\":\"delivery_time\",\"vendorName\":\"place_order_fullname\",\"amountDiff\":\"amount_diff\",\"actualDeliverTime\":\"actual_deliver_time\",\"priceDiff\":\"price_diff\",\"erpPo\":\"erp_po\",\"memberName\":\"inquiry_member_name\",\"customerOrderId\":\"order_customer_id\",\"inquryDelivery\":\"inqury_delivery\"}";
        JSONObject exportJson = JSON.parseObject(exportField);
        List<Map<String, Object>> fileData = data.stream().map(m -> {
            Map<String, Object> mf = new HashMap<>();
            for (String key : exportJson.keySet()) {
                mf.put(exportJson.getString(key), m.get(key));
            }
            return mf;
        }).collect(Collectors.toList());


        if (log.isDebugEnabled()) {
            log.debug("======================采购订单-数据分析-导出参数:reportType={},fileData={}", reportType.getId(), JSON.toJSONString(fileData));
        }
        ReportUtils.exportReport("order/order_tpi_report.jrxml", reportType.getId(), fileData);

        return SingleResponse.buildSuccess();
    }

    private List<TpiOrderModel> getNewData(List<String> ids) {
        SingleResponse<BOList> singleResponse = BoQueryUtils.Builder(ModelConst.T_ORDER_CUSTOMER_GOODS)
                .condition()
                .in("id", ids)
                .End().listBO();
//        if (!singleResponse.isSuccess()) {
//            return singleResponse;
//        }
        List<Map<String, Object>> orderCustomerGoodsMap = singleResponse.getData().getData();
//        List<OrderCustomerGoods> orderCustomerGoodsList = orderCustomerGoodsApi.list(OrderCustomerGoodsQuery.builder().id(ids).build()).getDataErrorThrow();
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(orderCustomerGoodsMap)) {
            return Collections.emptyList();
        }
        List<OrderCustomerGoods> orderCustomerGoodsList = BoUtils.copy2List(orderCustomerGoodsMap,OrderCustomerGoods.class);

        List<String> orderCustomerGoodsIds = orderCustomerGoodsList.stream().map(t -> t.getId().toString()).collect(Collectors.toList());

        SingleResponse<BOList> singleResponseAccept = BoQueryUtils.Builder(ModelConst.T_ORDER_GOODS_ACCEPT)
                .condition()
                .in("id", orderCustomerGoodsIds)
                .End().listBO();
        List<OrderGoodsAccept> orderGoodsAcceptList =BoUtils.copy2List(singleResponseAccept.getData().getData(),OrderGoodsAccept.class);
//        List<OrderGoodsAcceptVO> orderGoodsAcceptList = orderGoodsAcceptApi
//                .list(OrderGoodsAcceptQuery.builder().orderCustomerGoodsId(orderCustomerGoodsIds).build()).getDataErrorThrow();
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(orderGoodsAcceptList)) {
            orderGoodsAcceptList = Collections.emptyList();
        }

        SingleResponse<BOList> singleResponseReturn = BoQueryUtils.Builder(ModelConst.T_ORDER_GOODS_RETURNS)
                .condition()
                .in("id", orderCustomerGoodsIds)
                .End().listBO();
        List<OrderGoodsReturns> orderGoodsReturnsList =BoUtils.copy2List(singleResponseReturn.getData().getData(),OrderGoodsReturns.class);
//        List<OrderGoodsReturns> orderGoodsReturnsList = orderGoodsReturnsApi
//                .list(OrderGoodsReturnsQuery.builder().orderCustomerGoodsId(orderCustomerGoodsIds).build()).getDataErrorThrow();
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(orderGoodsReturnsList)) {
            orderGoodsReturnsList = Collections.emptyList();
        }

        List<TpiOrderModel> results = new ArrayList<>();
        for (OrderCustomerGoods orderCustomerGoods : orderCustomerGoodsList) {
            OrderGoodsAccept maxAccept = orderGoodsAcceptList.stream()
                    .filter(t -> t.getOrderCustomerGoodsId().equals(orderCustomerGoods.getId()))
                    .max(Comparator.comparing(OrderGoodsAccept::getCreatedTime)).orElse(null);

            List<OrderGoodsReturns> filterOrderGoodsReturnsList = orderGoodsReturnsList.stream()
                    .filter(t -> t.getOrderCustomerGoodsId().equals(orderCustomerGoods.getId())).collect(Collectors.toList());

            LocalDateTime deliveryTime = orderCustomerGoods.getPlace_order_time().plusDays(orderCustomerGoods.getDelivery().longValue());
            String deliveryTimeStr = DateUtils.localDateTimeToStr(deliveryTime);

            LocalDateTime actualDeliverTime = orderCustomerGoods.getActual_deliver_time();
            if (null == actualDeliverTime) {
                actualDeliverTime = DateUtils.toLocalDateTime(maxAccept.getCreatedTime());
            }
            TpiOrderModel model = TpiOrderModel.builder()
                    .id(orderCustomerGoods.getId().toString())
                    .erpPo(orderCustomerGoods.getOrderCustomer().getErpPO())
                    .name(orderCustomerGoods.getName())
                    .brand(orderCustomerGoods.getBrand())
                    .model(orderCustomerGoods.getModel())
                    .memberName(orderCustomerGoods.getPlaceOrderFullname())
                    .customerOrderId(orderCustomerGoods.getOrderCustomerId().toString())
                    .num(Objects.toString(BigDecimalUtils.round(orderCustomerGoods.getQuantity(), 4)))
                    .price(orderCustomerGoods.getPrice().toString())
                    .amount(orderCustomerGoods.getAmount().toString())
                    .delivery(orderCustomerGoods.getDelivery().toString())
                    .deliveryTime(deliveryTimeStr)
                    .actualDeliverTime(DateUtils.localDateTimeToStr(actualDeliverTime))
                    .bolRufund(org.apache.commons.collections4.CollectionUtils.isEmpty(filterOrderGoodsReturnsList) ? "否" : "是")
                    .refundReason(filterOrderGoodsReturnsList.stream().map(OrderGoodsReturns::getMemo).collect(Collectors.joining("---")))
                    .time(DateUtils.localDateTimeToStr(orderCustomerGoods.getPlace_order_time()))
                    .vendorName(orderCustomerGoods.getVendorOrganizationName())
//                    .bolInvite(OrganizationTypeEnum.PlatformVendor.des.equals(orderCustomerGoods.getOrderVendor().geto()) ? "否" : "是")
                    .bolOntime(null)
                    .build();
            results.add(model);
        }
        return results;
    }

    /**
     * 采购订单-订单商品-导出列表
     *
     * @param bo
     * @return
     */
    @Path("exporOrderCustomerGoods")
    @POST
    @Operation(summary = "采购订单-订单商品-导出列表", tags = CUSTOM_SERVICE, description = "入参:{data:{ids:[],fileType:'pdf/xlsx'}}")
    public SingleResponse exporOrderCustomerGoods(SaveOrUpdateBO bo) {
        List<String> ids = (List<String>) bo.getData().get("ids");
        if (ObjectUtils.isEmpty(ids)) {
            return SingleResponse.buildFailure("-1", "请求参数ids不能为空");
        }

        String fileType = (String) bo.getData().get("fileType");
        ReportType reportType = ReportType.get(fileType);

        if (reportType == null) {
            return SingleResponse.buildFailure("-1", "请求参数fileType不能为空");
        }

        SingleResponse<BOList> singleResponse = BoQueryUtils.Builder(ModelConst.T_ORDER_CUSTOMER_GOODS)
                .condition()
                .in("id", ids)
                .End().listBO();
        if (!singleResponse.isSuccess()) {
            return singleResponse;
        }
        List<Map<String, Object>> data = singleResponse.getData().getData();

        if (data.isEmpty()) {
            return SingleResponse.buildFailure("-1", "未获取到下载数据");
        }

        String exportField = "{\"id\":\"id\",\"time\":\"createdTime\",\"category\":\"category\",\"brand\":\"brand\",\"name\":\"name\",\"model\":\"model\",\"spec\":\"spec\",\"sku\":\"sku\",\"unit\":\"unit\",\"packageUnit\":\"package_unit\",\"packageNum\":\"package_quantity\",\"delivery\":\"delivery\",\"num\":\"num\",\"taxRate\":\"tax_rate\",\"pretaxPrice\":\"pretax_price\",\"price\":\"price\",\"amount\":\"amount\",\"status\":\"order_customer_goods_status\",\"memberName\":\"place_order_fullname\",\"orgName\":\"organization_name\",\"customerOrderId\":\"order_customer_id\",\"demandDeptName\":\"demand_department_name\",\"costCenterName\":\"cost_center_name\",\"inquiryMemberName\":\"inquiry_member_name\",\"inquiryId\":\"inquiry_id\",\"erpPO\":\"erp_po\"}";
        JSONObject exportJson = JSON.parseObject(exportField);
        List<Map<String, Object>> fileData = data.stream().map(m -> {
            Map<String, Object> mf = new HashMap<>();
            for (String key : exportJson.keySet()) {
                mf.put(exportJson.getString(key), m.get(key));
            }
            return mf;
        }).collect(Collectors.toList());


        if (log.isDebugEnabled()) {
            log.debug("======================采购订单-订单商品-导出参数:reportType={},fileData={}", reportType.getId(), JSON.toJSONString(fileData));
        }
        ReportUtils.exportReport("order/order_goods_report_xlsx.jrxml", reportType.getId(), fileData);

        return SingleResponse.buildSuccess();
    }

    /**
     * 采购订单-订单商品-导出未申请开票
     *
     * @param bo
     * @return
     */
    @Path("exporTradeOrderGoodsReport")
    @POST
    @Operation(summary = "采购订单-订单商品-导出未申请开票", tags = CUSTOM_SERVICE, description = "入参:{data:{ids:[],fileType:'pdf/xlsx'}}")
    public SingleResponse exporTradeOrderGoodsReport(TraderSaveOrUpdateBo bo) {
        List<String> ids = (List<String>) bo.getData().get("ids");
        if (ObjectUtils.isEmpty(ids)) {
            return SingleResponse.buildFailure("-1", "请求参数ids不能为空");
        }

        String fileType = (String) bo.getData().get("fileType");
        ReportType reportType = ReportType.get(fileType);

        if (reportType == null) {
            return SingleResponse.buildFailure("-1", "请求参数fileType不能为空");
        }

        SingleResponse<BOList> singleResponse = BoQueryUtils.Builder(ModelConst.T_ORDER_CUSTOMER_GOODS)
                .condition()
                .in("id", ids)
                .gt("delivery_time",bo.getDeliveryTimeStart())
                .lt("delivery_time",bo.getDeliveryTimeEnd())
                .End().listBO();
        if (!singleResponse.isSuccess()) {
            return singleResponse;
        }
        List<Map<String, Object>> data = singleResponse.getData().getData();

        if (data.isEmpty()) {
            return SingleResponse.buildFailure("-1", "未获取到下载数据");
        }

        String exportField = "{\"customerOrderId\":\"order_customer_id\",\"placeOrderTime\":\"place_order_time\",\"deliveryTime\":\"delivery_time\",\"actualOrder\":\"order_vendor_id\",\"goodsId\":\"goods_id\",\"brand\":\"brand\",\"name\":\"name\",\"model\":\"model\",\"spec\":\"spec\",\"num\":\"quantity\",\"unit\":\"unit\",\"pretaxPrice\":\"pretax_price\",\"price\":\"price\",\"taxRate\":\"tax_rate\",\"pretaxTotal\":\"pretax_total\",\"amount\":\"amount\",\"costCenterName\":\"cost_center_name\"}";
        JSONObject exportJson = JSON.parseObject(exportField);
        List<Map<String, Object>> fileData = data.stream().map(m -> {
            Map<String, Object> mf = new HashMap<>();
            for (String key : exportJson.keySet()) {
                mf.put(exportJson.getString(key), m.get(key));
            }
            return mf;
        }).collect(Collectors.toList());


        if (log.isDebugEnabled()) {
            log.debug("======================采购订单-订单商品-导出未申请开票:reportType={},fileData={}", reportType.getId(), JSON.toJSONString(fileData));
        }
        ReportUtils.exportReport("goods/trade_order_goods_report.jrxml", reportType.getId(), fileData);

        return SingleResponse.buildSuccess();
    }

    /**
     * 采购订单-客户订单详情-导出
     *
     * @param bo
     * @return
     */
    @Path("exporCustomerOrderDtailReport")
    @POST
    @Operation(summary = "采购订单-客户订单详情-导出", tags = CUSTOM_SERVICE, description = "入参:{data:{ids:[],fileType:'pdf/xlsx'}}")
    public SingleResponse exporCustomerOrderDtailReport(SaveOrUpdateBO bo) {
        List<String> ids = (List<String>) bo.getData().get("ids");
        if (ObjectUtils.isEmpty(ids)) {
            return SingleResponse.buildFailure("-1", "请求参数ids不能为空");
        }

        String fileType = (String) bo.getData().get("fileType");
        ReportType reportType = ReportType.get(fileType);

        if (reportType == null) {
            return SingleResponse.buildFailure("-1", "请求参数fileType不能为空");
        }

        SingleResponse<BOList> singleResponse = BoQueryUtils.Builder(ModelConst.T_ORDER_CUSTOMER_GOODS)
                .condition()
                .in("id", ids)
                .End().listBO();
        if (!singleResponse.isSuccess()) {
            return singleResponse;
        }
        List<Map<String, Object>> data = singleResponse.getData().getData();

        if (data.isEmpty()) {
            return SingleResponse.buildFailure("-1", "未获取到下载数据");
        }

        String exportField = "{\"customerOrderId\":\"order_customer_id\",\"erpPo\":\"erp_po\",\"memberName\":\"place_order_fullname\",\"status\":\"order_customer_goods_status\",\"customerOrderFreight\":\"freight\",\"customerOrderTotal\":\"total\",\"customerOrderAmount\":\"amount\",\"receiver\":\"receiver\",\"phone\":\"phone\",\"postal\":\"postal\",\"address\":\"address\",\"id\":\"id\",\"brand\":\"brand\",\"name\":\"name\",\"model\":\"model\",\"spec\":\"spec\",\"unit\":\"unit\",\"amount\":\"amount\",\"time\":\"createdTime\",\"num\":\"num\",\"price\":\"price\",\"sku\":\"sku\"}";
        JSONObject exportJson = JSON.parseObject(exportField);
        List<Map<String, Object>> fileData = data.stream().map(m -> {
            Map<String, Object> mf = new HashMap<>();
            for (String key : exportJson.keySet()) {
                mf.put(exportJson.getString(key), m.get(key));
            }
            return mf;
        }).collect(Collectors.toList());


        if (log.isDebugEnabled()) {
            log.debug("======================采购订单-客户订单详情-导出参数:reportType={},fileData={}", reportType.getId(), JSON.toJSONString(fileData));
        }
        ReportUtils.exportReport("order/customer_order_detail_report.jrxml", reportType.getId(), fileData);

        return SingleResponse.buildSuccess();
    }

    /**
     * 代购合同创建发货单并发货
     *
     * @param intentionId
     * @return
     */
    @Path("createdOrderAndDelivery")
    @POST
    @Operation(summary = "代购接口-代购合同创建发货单并发货", tags = CUSTOM_SERVICE)
    public SingleResponse createdOrderAndDelivery(@Parameter String intentionId) {
        return SingleResponse.of(contractService.saveOrderAndDelivery(intentionId));
    }

    /**
     * 移动端-首页-客户订单模糊搜索
     *
     * @param dto
     * @return
     */
    @Path("customerFuzzySearch")
    @POST
    @Operation(summary = "移动端-首页-客户订单模糊搜索", tags = CUSTOM_SERVICE, description = "pageIndex、pageSize必填,keyWord选填")
    public SingleResponse<BOList> customerFuzzySearch(@Parameter OrderCustomerDto dto) {
        log.info("------------------------移动端-首页-客户订单模糊搜索 customerFuzzySearch Param：{}------------------------", JsonUtils.toJson(dto));
        if (null == dto.getPageIndex() || null == dto.getPageSize()) {
            return SingleResponse.buildFailure("-1", "pageIndex、pageSize必填");
        }
        String tableName = getTableName(ModelConst.T_ORDER_CUSTOMER);
        String goodsTableName = getTableName(ModelConst.T_ORDER_CUSTOMER_GOODS);
        Map<String, Object> parameter = new HashMap<>();
        StringBuilder listSql = new StringBuilder();
        StringBuilder whereSql = new StringBuilder();
        StringBuilder countSql = new StringBuilder();
        listSql.append("select ocg.* from " + tableName + " oc " +
                "left join " + goodsTableName + " ocg on ocg.order_customer_id = oc.id " +
                "where oc.deleted ='0' and oc.enabled = true  and oc.order_customer_status " +
                "in ('" + OrderCustomerStatusEnum.UpcomingConfirm.name() + "','" + OrderCustomerStatusEnum.UpcomingDelivery.name() + "','" + OrderCustomerStatusEnum.DoneDelivery.name() + "')");

        countSql.append("select count(*) from " + tableName + " oc " +
                "left join " + goodsTableName + " ocg on ocg.order_customer_id = oc.id " +
                "where oc.deleted ='0' and oc.enabled = true  and oc.order_customer_status " +
                "in ('" + OrderCustomerStatusEnum.UpcomingConfirm.name() + "','" + OrderCustomerStatusEnum.UpcomingDelivery.name() + "','" + OrderCustomerStatusEnum.DoneDelivery.name() + "')");
        //商品名、客户订单号、客户名称、
        if (StringUtils.isNotBlank(dto.getKeyWord())) {
            whereSql.append(" and (ocg.name like :keyWord  or oc.organization_name like :keyWord or oc.id like :keyWord)");
            parameter.put("keyWord", "%"+dto.getKeyWord()+"%");
        }
        countSql.append(whereSql);
        listSql.append(whereSql);
        listSql.append(" order by oc.createdTime desc");
        listSql.append(" limit " + dto.getPageIndex() * dto.getPageSize() + ", " + dto.getPageSize());
        log.info("------------------------移动端-首页-客户订单模糊搜索 customerFuzzySearch listSql：{}------------------------parameter：{}", listSql, JsonUtils.toJson(parameter));
        List<Map<String, Object>> resultList = jdbcTemplate.queryForList(listSql.toString(), parameter);
        Integer count = 0;
        try {
            count = jdbcTemplate.queryForObject(countSql.toString(), parameter, Integer.class);
        } catch (DataAccessException e) {
            e.printStackTrace();
        }
        //构建结果集
        BoResultFormat.resultFormat(resultList, ModelConst.T_ORDER_CUSTOMER_GOODS);
        BOList bOList = new BOList();
        bOList.setData(resultList);
        bOList.setTotal(count);
        bOList.setSchemaCode(ModelConst.T_ORDER_CUSTOMER_GOODS);
        return SingleResponse.of(bOList);
    }
}
